﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Task;

namespace task
{
    public partial class FormMain : Form
    {
        private List<string> _types = new List<string>();
        private Dictionary<string, string> _subtypes = new Dictionary<string, string>();
        private List<Material> _materials = new List<Material>();

        public static readonly string DefaultPattern = @"[\[(（【]{0,1}[A-Za-z0-9]{1,8}[】)）\]\.、,，]{0,1}";

        public FormMain()
        {
            InitializeComponent();
            Init();
        }

        public void Init()
        {
            InitTypes();
            InitSubTypes();
            RefreshComponent();
        }

        private void RefreshComponent()
        {
            SetCbxType();
            SetCbxMaterialType();
            SetCbxMaterialSubType();
            RefreshTypeTree();
        }

        private void SetCbxMaterialSubType()
        {
            cbx_MaterialSubType.Items.Clear();
            foreach (var st in _subtypes.Where(st => st.Value == cbx_MaterialType.Text))
            {
                cbx_MaterialSubType.Items.Add(st.Key);
            }
        }

        private void SetCbxMaterialType()
        {
            cbx_MaterialType.Items.Clear();
            foreach (var type in _types)
            {
                cbx_MaterialType.Items.Add(type);
            }
        }

        private void SetCbxType()
        {
            cbx_Type.Items.Clear();
            foreach (var type in _types)
            {
                cbx_Type.Items.Add(type);
            }
        }

        private void InitTypes()
        {
            _types = DbHandler.GetAllType();
        }

        private void InitSubTypes()
        {
            _subtypes = DbHandler.GetAllSubType();
        }

        private void Btn_Data_Click(object sender, EventArgs e)
        {
            //展示所有数据
            General.FormData?.Dispose();
            General.FormData = new FormData(DbHandler.Search(""), _types, _subtypes);
            General.FormData.Show();
            Hide();
        }

        private void Btn_add_Click(object sender, EventArgs e)
        {
            try
            {
                var material = new Material
                {
                    Name = txt_MaterialName.Text,
                    Type = cbx_MaterialType.Text,
                    SubType = cbx_MaterialSubType.Text,
                    Content = txt_MaterialContent.Text
                };
                //去掉content中所有的空格
                material.Content = material.Content.Replace(" ", "");

                if (material.Type == "")
                {
                    throw new Exception("请选择类型！");
                }

                if (material.SubType == "")
                {
                    throw new Exception("所选子类不能为空！");
                }

                if (material.Content == "")
                {
                    var res = MessageBox.Show("您的素材内容为空，您确认要继续添加吗？", "请确认",
                        MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
                    if (res == DialogResult.Cancel)
                    {
                        return;
                    }
                }

                var contents = QueryContents();
                foreach (var c in contents)
                {
                    material.Content = c;
                    if (c.Length > 1) DbHandler.AddMaterial(material);
                }

                MessageBox.Show("添加成功！", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "异常", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void Btn_CreateType_Click(object sender, EventArgs e)
        {
            try
            {
                var typeName = txt_TypeName.Text;

                if (_types.Contains(typeName))
                {
                    throw new Exception("类型已存在，创建失败！");
                }

                if (typeName == "")
                {
                    throw new Exception("类型名不能为空！");
                }

                DbHandler.AddType(typeName);

                MessageBox.Show("添加类型成功", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                //重新初始化类型下拉列表
                InitTypes();
                RefreshComponent();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "异常", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void Btn_createSubType_Click(object sender, EventArgs e)
        {
            try
            {
                var name = txt_SubTypeName.Text;
                var type = cbx_Type.Text;

                if (!_types.Contains(type) || name == "")
                {
                    throw new Exception("类型名或子类型名不存在或为空！");
                }

                if (_subtypes.Any(item => item.Key.ToString() == name))
                {
                    throw new Exception("子类型名称已存在！");
                }

                DbHandler.AddSubType(name, type);
                MessageBox.Show("添加子类型成功", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                //重新初始化子类型下拉列表
                InitSubTypes();
                RefreshComponent();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "异常", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void Cbx_MaterialType_SelectedIndexChanged(object sender, EventArgs e)
        {
            SetCbxMaterialSubType();
        }

        private void Btn_clear_Click(object sender, EventArgs e)
        {
            txt_MaterialContent.Text = "";
            txt_MaterialName.Text = "";
            txt_SubTypeName.Text = "";
            txt_TypeName.Text = "";
        }

        private List<string> QueryContents()
        {
            var contents = new List<string>();
            var queryStr = txt_MaterialContent.Text;
            if (ckb_Remove.Checked)
            {
                queryStr = cbx_remove.Items.Cast<string>()
                    .Aggregate(queryStr, (current, item) => Regex.Replace(current, @"" + item, ""));
            }

            if (ckb_Replace.Checked)
            {
                queryStr = cbx_replace.Items.Cast<string>().Aggregate(queryStr,
                    (current, item) => Regex.Replace(current, @"" + item, cbx_replaceTo.Items.ToString()));
            }

            if (ckb_Mark.Checked)
            {
                string pattern;
                var otherPatternFlag = false;
                switch (cbx_Query.SelectedIndex)
                {
                    case 0:
                        pattern = DefaultPattern;
                        break;
                    case 1:
                        pattern = @"\r\n";
                        otherPatternFlag = true;
                        break;
                    default:
                        pattern = @"" + cbx_Query.Text;
                        otherPatternFlag = true;
                        break;
                }

                if (pattern == null) return contents;
                var vs = Regex.Split(queryStr, pattern);
                contents = new List<string>(vs);
                if (!otherPatternFlag) contents.RemoveAt(0);
            }
            else
            {
                contents.Add(queryStr);
            }

            return contents;
        }

        private void Ckb_Query_CheckedChanged(object sender, EventArgs e)
        {
            cbx_Query.Visible = ckb_Mark.Checked;
        }

        private void Btn_BackUp_Click(object sender, EventArgs e)
        {
            try
            {
                DbHandler.Backup();
                MessageBox.Show("备份成功！", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show("备份失败：" + ex.Message, "备份失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void Btn_Restore_Click(object sender, EventArgs e)
        {
            try
            {
                DbHandler.Restore();
                MessageBox.Show("还原成功！", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show("还原失败：" + ex.Message, "还原失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void Frm_Main_FormClosing(object sender, FormClosingEventArgs e)
        {
            var res = MessageBox.Show("您还未备份表，您现在要进行备份吗？", "请选择", MessageBoxButtons.YesNoCancel,
                MessageBoxIcon.Warning);
            switch (res)
            {
                case DialogResult.Cancel:
                    //阻止退出系统
                    e.Cancel = true;
                    return;
                case DialogResult.Yes:
                    Btn_BackUp_Click(sender, e);
                    break;
            }

            Environment.Exit(0);
        }

        private void RefreshTypeTree()
        {
            foreach (var type in _types)
            {
                TreeNode node = new TreeNode(type);
                foreach (var subNodes in from subtype in _subtypes
                    where subtype.Value == type
                    select new TreeNode(subtype.Key))
                {
                    node.Nodes.Add(subNodes);
                }

                tree_Type.Nodes.Add(node);
            }
        }

        private void tree_Type_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Button != MouseButtons.Right) return;
            General.FormData?.Dispose();
            if (e.Node.Parent != null)
            {
                General.FormData = new FormData(DbHandler.SubTypeSearch(e.Node.Parent.Text, e.Node.Text), _types,
                    _subtypes);
                General.FormData.Show();
            }
            else
            {
                General.FormData = new FormData(DbHandler.TypeSearch(e.Node.Text), _types, _subtypes);
                General.FormData.Show();
            }
        }

        private void Ckb_Remove_CheckedChanged(object sender, EventArgs e)
        {
            cbx_remove.Visible = ckb_Remove.Checked;
        }

        private void Ckb_Replace_CheckedChanged(object sender, EventArgs e)
        {
            cbx_replace.Visible = ckb_Replace.Checked;
            cbx_replaceTo.Visible = ckb_Replace.Checked;
            lab_rep.Visible = ckb_Replace.Checked;
        }

        private void Rem_add_Click(object sender, EventArgs e)
        {
            cbx_remove.Items.Add(cbx_remove.Text);
        }

        private void Rem_del_Click(object sender, EventArgs e)
        {
            cbx_remove.Items.Remove(cbx_remove.Text);
        }

        private void Rem_delAll_Click(object sender, EventArgs e)
        {
            cbx_remove.Items.Clear();
            cbx_remove.Text = "";
        }

        private void Rep_add_Click(object sender, EventArgs e)
        {
            cbx_replace.Items.Add(cbx_replace.Text);
        }

        private void Rep_del_Click(object sender, EventArgs e)
        {
            cbx_replace.Items.Remove(cbx_replace.Text);
        }

        private void Rep_delAll_Click(object sender, EventArgs e)
        {
            cbx_replace.Items.Clear();
            cbx_replace.Text = "";
        }

        private void Rpt_add_Click(object sender, EventArgs e)
        {
            cbx_replaceTo.Items.Add(cbx_replaceTo.Text);
        }

        private void Rpt_del_Click(object sender, EventArgs e)
        {
            cbx_replaceTo.Items.Remove(cbx_replace.Text);
        }

        private void Rpt_delAll_Click(object sender, EventArgs e)
        {
            cbx_replaceTo.Items.Clear();
            cbx_replaceTo.Text = "";
        }

        private void link_version_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            MessageBox.Show(General.Version);
        }
    }
}